// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.assets.service.impl;

import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.assets.dto.ImportAssetsProjectDto;
import com.liuxinlong.modules.assets.service.AssetsProjectService;
import com.liuxinlong.modules.dao.AssetsDepartmentDao;
import com.liuxinlong.modules.dao.AssetsProjectDao;
import com.liuxinlong.modules.dao.PatentDepartmentDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.AssetsProject;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 固资项目管理业务接口层实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2024-01-15
 */
@Service
@Slf4j
public class AssetsProjectServiceImpl implements AssetsProjectService {

    @Autowired
    private AssetsProjectDao assetsProjectDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private AssetsDepartmentDao assetsDepartmentDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private PatentDepartmentDao patentDepartmentDao;

    @Override
    @Transactional
    public List<Map<String, Object>> pageAssetsProjectInfo(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<AssetsProject> originalList = assetsProjectDao.pageAssetsProjectInfo(queryParam);
        List<Map<String, Object>> resultList = completeResult(originalList, startNum);
        return resultList;
    }

    @Override
    public int getAssetsProjectInfoCount(Map<String, Object> queryParam) {
        return assetsProjectDao.getAssetsProjectInfoCount(queryParam);
    }

    @Override
    @Transactional
    public void addAssetsProjectInfo(AssetsProject assetsProject) {
        String id = SnowFlake.nextIdStr();
        assetsProject.setId(id);
        assetsProject.setProjectNo(assetsProject.getProjectNo().trim().toUpperCase());
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        assetsProject.setCreateUser(currentUser.getId());
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        assetsProject.setCreateTime(currentTime);
        assetsProjectDao.insert(assetsProject);
    }

    @Override
    @Transactional
    public void updateAssetsProjectInfo(AssetsProject assetsProject) {
        String id = assetsProject.getId();
        if (StringUtils.isEmpty(id)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改项目信息失败，项目信息不存在！");
        }
        AssetsProject oldInfo = assetsProjectDao.selectById(id);
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改项目信息失败，项目信息不存在！");
        }
        assetsProject.setProjectNo(assetsProject.getProjectNo().trim().toUpperCase());
        assetsProject.setCreateTime(oldInfo.getCreateTime());
        assetsProject.setCreateUser(oldInfo.getCreateUser());
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        assetsProject.setUpdateUser(currentUser.getId());
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        assetsProject.setUpdateTime(currentTime);
        assetsProjectDao.updateById(assetsProject);
    }

    @Override
    @Transactional
    public void deleteAssetsProjectInfo(String id) {
        AssetsProject assetsProject = assetsProjectDao.selectById(id);
        if (ObjectUtils.isEmpty(assetsProject)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "删除失败，项目信息不存在！");
        }
        assetsProjectDao.deleteById(id);
    }

    @Override
    public void exportAssetsProject(Map<String, Object> queryParam, HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("固资项目导出excel.xlsx");
        queryParam.put("startNum", 0);
        queryParam.put("pageSize", 10000);
        List<AssetsProject> assetsProjectList = assetsProjectDao.pageAssetsProjectInfo(queryParam);
        Map<String, Map<String, String>> departmentMap = patentDepartmentDao.getDepartmentMap();
        String[] head = {"序号", "项目号", "项目描述", "部门", "SBU"};
        data.setHead(head);
        String[][] dataList = new String[assetsProjectList.size()][head.length];
        int index = 0;
        for (AssetsProject assetsProject : assetsProjectList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = assetsProject.getProjectNo();
            dataList[index][2] = assetsProject.getProjectName();
            dataList[index][3] = departmentMap.containsKey(assetsProject.getDepartment()) ? departmentMap.get(assetsProject.getDepartment()).get("name") : "";
            dataList[index][4] = assetsProject.getProductType();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public ImportResp importAssetsProject(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                AssetsProject assetsProject = covertToBean(record);
                return false;
//				try {
//					materialStandardDao.insert(mocDetail);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetCode(ReturnCodes.HTTP_SUCCESS.getRetCode());
                resp.setRetMessage("导入固资项目数据部分失败，总数=" + resp.getTotal() + ",失败总数=" +
                        resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入固资项目数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap();
                    item.put("sort", sort);
                    item.put("projectNo", failRecord[0].trim().toUpperCase());
                    item.put("projectName", failRecord[1]);
                    item.put("productType", failRecord[2]);
                    item.put("department", failRecord[3].trim().toUpperCase());
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    @Override
    public ImportResp batchAddAssetsProject(List<ImportAssetsProjectDto> dataList) {
        Map<String, Map<String, String>> projectNoMap = assetsProjectDao.getAssetsProjectMapBySn();
        Map<String, Map<String, String>> departmentMap = assetsDepartmentDao.getAssetsDepartmentMapBySn();
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        List<Map> failedList = new ArrayList<>();
        boolean insertSuccess;
        int sort = 1;
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        for (ImportAssetsProjectDto assetsProjectDto : dataList) {
            AssetsProject assetsProject = new AssetsProject();
            assetsProject.setId(SnowFlake.nextIdStr());
            assetsProject.setProjectName(assetsProjectDto.getProjectName());
            assetsProject.setProductType(assetsProjectDto.getProductType());
            if (StringUtils.isNotEmpty(assetsProjectDto.getProjectNo()) && projectNoMap.containsKey(assetsProjectDto.getProjectNo())) {
                Map item = ObjectUtils.object2Map(assetsProjectDto);
                item.put("message", "项目号已存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            assetsProject.setProjectNo(assetsProjectDto.getProjectNo().trim().toUpperCase());
            if (!departmentMap.containsKey(assetsProjectDto.getDepartment().trim().toUpperCase())) {
                Map item = ObjectUtils.object2Map(assetsProjectDto);
                item.put("message", "部门不存在！");
                item.put("sort", sort);
                failedList.add(item);
                sort++;
                continue;
            }
            assetsProject.setDepartment(departmentMap.get(assetsProjectDto.getDepartment()).get("department"));
            assetsProject.setCreateTime(currentTime);
            assetsProject.setCreateUser(userId);
            String message = "";
            try {
                assetsProjectDao.insert(assetsProject);
                insertSuccess = true;
            } catch (Exception e) {
                insertSuccess = false;
                message = e.getMessage();
            }
            if (!insertSuccess) {
                Map<String, Object> map = ObjectUtils.object2Map(assetsProjectDto);
                map.put("sort", sort);
                map.put("message", message);
                sort++;
                failedList.add(map);
            }
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(failedList.size() > 0 ? ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() :
                ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setFailedList(failedList);
        resp.setTotal(dataList.size());
        resp.setSuccessTotal(dataList.size() - failedList.size());
        resp.setFailedTotal(failedList.size());
        resp.setRetMessage(failedList.size() > 0 ? "导入固资项目信息部分成功" : "导入固资项目信息成功");
        return resp;
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private AssetsProject covertToBean(String[] record) {
        AssetsProject assetsProject = new AssetsProject();
        assetsProject.setProjectNo(record[0].trim());
        assetsProject.setProjectName(record[1].trim());
        assetsProject.setProductType(record[2].trim());
        assetsProject.setDepartment(record[3].trim());
        return assetsProject;

    }
    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("项目号不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 20) {
                addRowError("项目号长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("项目描述不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 100) {
                addRowError("项目描述字段非法", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[3].trim())) {
            addRowError("部门不能为空", rowErrors);
        } else {
            if (record[3].trim().length() > 100) {
                addRowError("部门长度不能超过100", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

    /**
     * 补全数据
     *
     * @param originalList 原始数据
     * @param startNum     数据起始值
     * @return 补全数据列表
     */
    private List<Map<String, Object>> completeResult(List<AssetsProject> originalList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String,Map<String,String>> departmentMap = patentDepartmentDao.getDepartmentMap();
        int sort = startNum + 1;
        for (AssetsProject assetsProject : originalList) {
            Map<String, Object> item = ObjectUtils.object2Map(assetsProject);
            item.put("sort", sort);
            item.put("departmentName",departmentMap.containsKey(assetsProject.getDepartment()) ?
                    departmentMap.get(assetsProject.getDepartment()).get("name") : "");
            resultList.add(item);
            sort++;
        }
        return resultList;
    }
}
